package com.example.ezviz_plugin;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;

import com.example.ezviz_plugin.platformView.RelativeLayoutPlatformFactory;
import com.example.ezviz_plugin.platformView.SurfaceViewPlatformFactory;
import com.example.ezviz_plugin.util.Constants;
import com.videogo.constant.Constant;
import com.videogo.exception.BaseException;
import com.videogo.openapi.EZConstants;
import com.videogo.openapi.EZOpenSDK;
import com.videogo.openapi.EZPlayer;
import com.videogo.util.LocalInfo;
import com.videogo.util.LogUtil;
import com.videogo.util.Utils;
import com.videogo.widget.CustomRect;
import com.videogo.widget.CustomTouchListener;

import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/** EzvizPlugin */
public class EzvizPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, Handler.Callback, SurfaceHolder.Callback {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private EventChannel eventChannel;
  private static Activity activity;
  private static Application application;
  private static Context context;
  private static final String TAG = "EzvizFlutterPlugin";
  // 播放器
  private EZPlayer mPlayer;
  // 保存localInfo实例
  private LocalInfo mLocalInfo;
  // 保存eventChannel的events
  private EventChannel.EventSink eventSink;
  private String appKey;
  private String accessToken;
  private String deviceSerial;
  private int cameraNo;
  private Handler mHandler;
  private SurfaceHolder surfaceHolder;
  private RelativeLayoutPlatformFactory relativeLayoutPlatformFactory;
  
  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "ezviz_plugin");
    channel.setMethodCallHandler(this);
    context = flutterPluginBinding.getApplicationContext();
    mHandler = new Handler(this);
    relativeLayoutPlatformFactory = new RelativeLayoutPlatformFactory();
    eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "ezviz_flutter_plugin_event_channel");
    eventChannel.setStreamHandler(new EventChannel.StreamHandler() {
      @Override
      public void onListen(Object arguments, EventChannel.EventSink events) {
        eventSink = events;
      }

      @Override
      public void onCancel(Object arguments) {
        eventSink = null;
      }
    });

    // 注册
    flutterPluginBinding.getPlatformViewRegistry()
            .registerViewFactory(
                    "ezviz_flutter_plugin_android_view",
                    relativeLayoutPlatformFactory
            );
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }

  @Override
  public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
    activity = binding.getActivity();
    application = activity.getApplication();
  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {

  }

  @Override
  public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {

  }

  @Override
  public void onDetachedFromActivity() {

  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    switch (call.method) {
      case "getPlatformVersion":
        result.success("Android " + android.os.Build.VERSION.RELEASE);
        break;
      case "init": // 初始化
        String appKey = call.argument("appKey");
        this.appKey = appKey;
        Log.e(TAG, "获取到的AppKey: " + appKey + (appKey == null));
        // 初始化SDK
        init(appKey, result);
        break;
      case "startToPlay": // 开始播放
        accessToken = call.argument("accessToken");
        deviceSerial = call.argument("deviceSerial");
        String cameraNoStr = call.argument("cameraNo");
        // 开始播放
        startToPlay(accessToken, deviceSerial, cameraNoStr);
        break;
      case "stopToPlay": // 停止播放
        if (mPlayer != null) mPlayer.stopRealPlay();
        break;
      case "logout": // 退出登录授权
        EZOpenSDK.getInstance().logout();
        break;
      case "openSound": // 开启声音
        if (mPlayer != null) mPlayer.openSound();
        break;
      case "closeSound": // 关闭声音
        if (mPlayer != null) mPlayer.closeSound();
        break;
      case "release": // 释放播放器资源
        releasePlayer();
        break;
      case "setDirection": // 移动方向
        String directionStr = call.argument("direction");
        boolean stop = call.argument("stop");
        int movingDirection = Integer.valueOf(directionStr);
        ptzOption(movingDirection, stop);
        break;
      case "enterFullScreen":
        handleFullScreenMode(true);
        // changeScreenSize();
        break;
      case "exitFullScreen":
        handleFullScreenMode(false);
        // changeScreenSize();
        break;
      default:
        result.notImplemented();
    }
  }
  
  public void changeScreenSize() {
    RelativeLayout.LayoutParams svLp = new RelativeLayout.LayoutParams(
            100, 100
    );
    relativeLayoutPlatformFactory.getSurfaceView().setLayoutParams(svLp);
  }

  /**
   * 使用传递appKey初始化
   * @param appKey
   * @param result
   */
  public void init(String appKey, Result result) {
    // sdk日志开关，正式发布需要去掉
    EZOpenSDK.showSDKLog(true);

    // 设置是否支持P2P取流,详见api
    EZOpenSDK.enableP2P(false);
    Log.e(TAG, "初始化前的sdk实例：" + EZOpenSDK.getInstance());

    // APP_KEY请替换成自己申请的
    boolean initResult = EZOpenSDK.initLib(application, appKey == null ? Constants.APP_KEY : appKey);
    result.success(initResult);
    Log.e(TAG, "初始化后的sdk实例：" + EZOpenSDK.getInstance());
  }

  /**
   * 使用默认appKey初始化
   */
  public void init() {
    // sdk日志开关，正式发布需要去掉
    EZOpenSDK.showSDKLog(true);

    // 设置是否支持P2P取流,详见api
    EZOpenSDK.enableP2P(false);

    // APP_KEY请替换成自己申请的
    EZOpenSDK.initLib(application, appKey == null ? Constants.APP_KEY : appKey);
  }

  /**
   * 开始播放
   * @param accessToken
   * @param deviceSerial
   * @param cameraNoStr
   */
  public void startToPlay(String accessToken, String deviceSerial, String cameraNoStr) {
    Log.e(TAG, "调用播放方法");
    EZOpenSDK instance = EZOpenSDK.getInstance();
    if (instance == null) {
      init();
      instance = EZOpenSDK.getInstance();
    }
    instance.setAccessToken(accessToken);
    if (mPlayer == null) {
      SurfaceView surfaceView = relativeLayoutPlatformFactory.getSurfaceView();
      relativeLayoutPlatformFactory.getRelativeLayout().addView(surfaceView);
      surfaceHolder = surfaceView.getHolder();
      surfaceHolder.addCallback(this);
      // 保存
      cameraNo = cameraNoStr == null ? Constants.CAMERA_NO : Integer.valueOf(cameraNoStr);
      // 播放器
      mPlayer = EZOpenSDK.getInstance().createPlayer(
              deviceSerial, cameraNo
      );
      // 设置消息处理
      mPlayer.setHandler(mHandler);
    } else {
      mPlayer.startRealPlay();
    }
  }

  /**
   * 释放播放器资源
   */
  private void releasePlayer() {
    if (mPlayer == null) return;
    mPlayer.closeSound();
    mPlayer.stopRealPlay();
    mPlayer.release();
    mPlayer = null;
  }

  /**
   * 匹配摄像头移动command
   * @param direction
   * @return
   */
  public EZConstants.EZPTZCommand matchPTZCommand(int direction) {
    EZConstants.EZPTZCommand command = null;
    switch (direction) {
      case 0:
        command = EZConstants.EZPTZCommand.EZPTZCommandUp;
        break;
      case 1:
        command = EZConstants.EZPTZCommand.EZPTZCommandDown;
        break;
      case 2:
        command = EZConstants.EZPTZCommand.EZPTZCommandLeft;
        break;
      case 3:
        command = EZConstants.EZPTZCommand.EZPTZCommandRight;
        break;
    }
    return command;
  }

  /**
   * 控制摄像头移动
   * @param direction
   * @param stop
   */
  public void ptzOption(final int direction, final boolean stop) {
    new Thread(new Runnable() {
      @Override
      public void run() {
        EZConstants.EZPTZCommand command = matchPTZCommand(direction);
        try {
          EZOpenSDK.getInstance().controlPTZ(
                  deviceSerial,
                  cameraNo,
                  command,
                  stop ? EZConstants.EZPTZAction.EZPTZActionSTOP : EZConstants.EZPTZAction.EZPTZActionSTART,
                  EZConstants.PTZ_SPEED_DEFAULT
          );
        } catch (BaseException e) {
          e.printStackTrace();
        }
      }
    }).start();
  }

  /**
   * 进入或退出全屏
   * @param enable
   */
  private void handleFullScreenMode(boolean enable) {
    if (enable) {
      LogUtil.e(TAG, "进入全屏");
      WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
      lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
      activity.getWindow().setAttributes(lp);
      activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
      // 设置横屏
      activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    } else {
      LogUtil.e(TAG, "退出全屏");
      WindowManager.LayoutParams attr = activity.getWindow().getAttributes();
      attr.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
      activity.getWindow().setAttributes(attr);
      activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
      // 退出横屏
      activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
//    setRealPlaySvLayout();
    changeScreenSize();
  }

  /**
   * 获取状态栏高度
   * @param context
   * @return
   */
  private int getStatusBarHeight(Context context) {
    int result = 0;
    int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
      result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
  }

  /**
   * 横竖屏切换
   */
  private void setRealPlaySvLayout() {
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics outMetrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(outMetrics);
    // 状态栏高度
    final int statusBarHeight = getStatusBarHeight(context);
    // 屏幕宽
    final int screenWidth = outMetrics.widthPixels;
    // 屏幕高
    final int screenHeightPixels = outMetrics.heightPixels;

    int orientation = activity.getResources().getConfiguration().orientation;
    LogUtil.e(TAG, "获取到的屏幕宽度：" + screenWidth +"当前的屏幕状态："+orientation + "状态栏高度" + statusBarHeight);
  }

  @Override
  public boolean handleMessage(Message msg) {
    Log.e(TAG, "获取到的消息类型id：" + msg.what);
    // 通过eventChannel发送到flutter
    eventSink.success(msg.what);
    switch (msg.what) {
      // 播放成功
      case EZConstants.EZRealPlayConstants.MSG_REALPLAY_PLAY_SUCCESS:
        mPlayer.openSound(); // 开启声音
        break;
      case EZConstants.EZRealPlayConstants.MSG_REALPLAY_PLAY_FAIL:
        mPlayer.closeSound(); // 关闭声音
        break;
    }
    return false;
  }

  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    mPlayer.setSurfaceHold(holder);
    mPlayer.startRealPlay();
     LogUtil.e(TAG, "plugin当前的surface回调 ---- surfaceCreated");
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
     LogUtil.e(TAG, "plugin当前的surface回调 ---- surfaceChanged");
    mPlayer.setSurfaceHold(holder);
  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
     LogUtil.e(TAG, "plugin当前的surface回调 ---- surfaceDestroyed");
    mPlayer.setSurfaceHold(null);
    // 当播放尺寸发生变化时，将消息发送发送到flutter，显示loading
    eventSink.success(1000);
  }
}
